﻿/*
* jQuery.upload v1.0.2
*
* Copyright (c) 2010 lagos
* Dual licensed under the MIT and GPL licenses.
*
* http://lagoscript.org
*/
(function ($) {

    var uuid = 0;

    $.fn.upload = function (url, data, callback, type) {
        var self = this, inputs, checkbox, checked,
			iframeName = 'jquery_upload' + ++uuid,
			iframe = $('<iframe name="' + iframeName + '" style="position:absolute;top:-9999px" />').appendTo('body'),
			form = '<form target="' + iframeName + '" method="post" enctype="multipart/form-data" />';

        if ($.isFunction(data)) {
            type = callback;
            callback = data;
            data = {};
        }

        checkbox = $('input:checkbox', this);
        checked = $('input:checked', this);
        form = self.wrapAll(form).parent('form').attr('action', url);

        // Make sure radios and checkboxes keep original values
        // (IE resets checkd attributes when appending)
        checkbox.removeAttr('checked');
        checked.attr('checked', true);

        inputs = createInputs(data);
        inputs = inputs ? $(inputs).appendTo(form) : null;

        form.submit(function () {
            iframe.load(function () {
                var data = handleData(this, type),
					checked = $('input:checked', self);

                form.after(self).remove();
                checkbox.removeAttr('checked');
                checked.attr('checked', true);
                if (inputs) {
                    inputs.remove();
                }

                setTimeout(function () {
                    iframe.remove();
                    if (type === 'script') {
                        $.globalEval(data);
                    }
                    if (callback) {
                        callback.call(self, data);
                    }
                }, 0);
            });
        }).submit();

        return this;
    };

    function createInputs(data) {
        return $.map(param(data), function (param) {
            return '<input type="hidden" name="' + param.name + '" value="' + param.value + '"/>';
        }).join('');
    }

    function param(data) {
        if ($.isArray(data)) {
            return data;
        }
        var params = [];

        function add(name, value) {
            params.push({ name: name, value: value });
        }

        if (typeof data === 'object') {
            $.each(data, function (name) {
                if ($.isArray(this)) {
                    $.each(this, function () {
                        add(name, this);
                    });
                } else {
                    add(name, $.isFunction(this) ? this() : this);
                }
            });
        } else if (typeof data === 'string') {
            $.each(data.split('&'), function () {
                var param = $.map(this.split('='), function (v) {
                    return decodeURIComponent(v.replace(/\+/g, ' '));
                });

                add(param[0], param[1]);
            });
        }

        return params;
    }

    function handleData(iframe, type) {
        var data, contents = $(iframe).contents().get(0);

        if ($.isXMLDoc(contents) || contents.XMLDocument) {
            return contents.XMLDocument || contents;
        }
        data = $(contents).find('body').html();

        switch (type) {
            case 'xml':
                data = parseXml(data);
                break;
            case 'json':
                data = window.eval('(' + data + ')');
                break;
        }
        return data;
    }

    function parseXml(text) {
        if (window.DOMParser) {
            return new DOMParser().parseFromString(text, 'application/xml');
        } else {
            var xml = new ActiveXObject('Microsoft.XMLDOM');
            xml.async = false;
            xml.loadXML(text);
            return xml;
        }
    }

})(jQuery);